package com.example.jacky.uilibrary.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import com.example.jacky.uilibrary.R;

public class ImageTextView extends View {

    private static final int CENTER = 0; // 居中
    private static final int LEFT = 1; // 左对齐
    private static final int RIGHT = 2; // 右对齐

    // 没有设置值
    private static final int NO_VALUE = -1;

    /**
     * 默认的文字对齐方式
     */
    private static final int DEFAULT_TXT_GRAVITY = CENTER;
    /**
     * 默认的图片对齐方式
     */
    private static final int DEFAULT_IMG_GRAVITY = CENTER;

    /**
     * 默认的字体颜色 红色
     */
    private static final int DEFAULT_TXT_COLOR = Color.RED;

    /**
     * 设置默认字体大小 默认12sp
     */
    private final int DEFAULT_TXT_SIZE = (int) TypedValue.
            applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, getResources().getDisplayMetrics());

    /**
     * 设置默认的文字和图片之间的间距 默认10dp
     */
    private final int DEFAULT_TXT_IMG_PADDING = (int) TypedValue.
            applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());

    private String mTxt; // 文字

    private Bitmap mImg; // 图片

    private int mTxtSize; // 文字尺寸 不可以设置为0 当为的0时候默认处理为默认字体大小

    private int mTxtColor = NO_VALUE; // 文字颜色 当没有设置该值的时候 处理为使用默认颜色

    private int mTxtImgPadding; // 文字和图片之间的间距 不可以设置为0 当为0 的时候默认处理为默认间距大小

    private int mTxtGravity = NO_VALUE; // 文字的对齐方式

    private int mImgGravity = NO_VALUE; // 图片的对齐方式

    private Paint mPaint; // 画笔
    private Rect mTxtRect; // 文字区域
    private Rect mRect; // 整个内容区域

    private float txtWidth; // 文字宽度
    private float txtHeight; // 文字高度

    private int width = 0, height = 0; // View 宽高

    public ImageTextView(Context context) {
        this(context, null);
    }

    public ImageTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ImageTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    Paint.FontMetrics fm;

    /**
     * 实现初始化操作
     *
     * @param context
     * @param attrs
     * @param defStyle
     */
    private void init(Context context, AttributeSet attrs, int defStyle) {
        // 得到自定义属性
        TypedArray array = context.getTheme().
                obtainStyledAttributes(attrs, R.styleable.ImageTextView, defStyle, 0);
        // 得到自定义属性个数
        int count = array.getIndexCount();
        // 遍历属性
        for (int i = 0; i < count; i++) {
            int attr = array.getIndex(i);

            if (attr == R.styleable.ImageTextView_itvTxt) {
                mTxt = array.getString(attr);

            } else if (attr == R.styleable.ImageTextView_itvTxtSize) {
                mTxtSize = array.getDimensionPixelSize(attr, DEFAULT_TXT_SIZE);

            } else if (attr == R.styleable.ImageTextView_itvTxtColor) {
                mTxtColor = array.getColor(attr, DEFAULT_TXT_COLOR);

            } else if (attr == R.styleable.ImageTextView_itvTxtGravity) {
                mTxtGravity = array.getInt(attr, DEFAULT_TXT_GRAVITY);

            } else if (attr == R.styleable.ImageTextView_itvImgSrc) {// 通过资源文件加载图片 默认 小机器人是 默认显示图片
                mImg = BitmapFactory.decodeResource(getResources(),
                        array.getResourceId(attr, R.mipmap.ic_launcher));

            } else if (attr == R.styleable.ImageTextView_itvImgGravity) {
                mImgGravity = array.getInt(attr, DEFAULT_IMG_GRAVITY);

            } else if (attr == R.styleable.ImageTextView_itvTxtImgPadding) {
                mTxtImgPadding = array.getDimensionPixelSize(attr, DEFAULT_TXT_IMG_PADDING);

            }
        }
        // 释放
        array.recycle();

        // 实例化 画笔和区域
        mPaint = new Paint();
        mTxtRect = new Rect();
        mRect = new Rect();

        // 对文字进行测量
        mPaint.getTextBounds(mTxt, 0, mTxt.length(), mTxtRect);

        // 以下提供更加准确的获取文字的宽高的方法
        // baseLine 概念 drawText 的时候 的坐标即为 baseline
        // 1. 获取文字的宽度
        txtWidth = mPaint.measureText(mTxt, 0, mTxt.length());
        // 对比上面这个方法 获取的宽度 更加准确一点 是单精度的 通过getTextBounds 获取到的是进过int转换的 失去了精度
        // 2. 获取文字高度
        /*fm = mPaint.getFontMetrics();
        Log.e("tag", "ascent [ " + fm.ascent + " ]");
        Log.e("tag", "descent [ " + fm.descent + " ]");
        Log.e("tag", "top [ " + fm.top + " ]");
        Log.e("tag", "bottom [ " + fm.bottom + " ]");
        Log.e("tag", "leading [ " + fm.leading + " ]");*/

    }

    /**
     * 进行测量
     *
     * @param widthMeasureSpec  宽度的测量值
     * @param heightMeasureSpec 高度的测量值
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 得到宽度的测量模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        // 得到宽的测量值
        int widthMeasure = MeasureSpec.getSize(widthMeasureSpec);

        // 得到高度的测量模式
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        // 得到高度的测量值
        int heightMeasure = MeasureSpec.getSize(heightMeasureSpec);


        // 根据模式判断 确定当前的宽高值
        if (widthMode == MeasureSpec.EXACTLY) {
            // 直接赋值
            width = widthMeasure;
        } else {
            if (widthMode == MeasureSpec.AT_MOST) {
                // 进行自己测量计算
                /**
                 * 由于有图片和文字俩部分内容组成
                 * 所以需要分别对俩个部分进行测量
                 * 然后取这俩个里面较大的那个值 与 分配的测量值 进行对比
                 * 取较小的值
                 */
                // 得到由图片决定的宽度
                int imgWidth = mImg.getWidth() + getPaddingLeft() + getPaddingRight();
                // 得到由文字决定的宽度
                int txtWidth = mTxtRect.width() + getPaddingLeft() + getPaddingRight();
                // 得到较大的一个宽度作为临时宽度
                int tempWidth = Math.max(imgWidth, txtWidth);
                // 对比分配的测量值
                width = Math.min(tempWidth, widthMeasure);
            } else { //UNSPECIFIED
                int imgWidth = mImg.getWidth() + getPaddingLeft() + getPaddingRight();
                // 得到由文字决定的宽度
                int txtWidth = mTxtRect.width() + getPaddingLeft() + getPaddingRight();
                // 得到较大的一个宽度作为临时宽度
                int tempWidth = Math.max(imgWidth, txtWidth);
                height = tempWidth;
            }
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightMeasure;
        } else {
            if (heightMode == MeasureSpec.AT_MOST) {
                // 进行自己测量
                // 图片高度 + 文字高度 + 上下内边距 + 文字和图片之间的间距
                int imgHeight = mImg.getHeight();
                int txtHeight = mTxtRect.height();
                int tempHeight = imgHeight + txtHeight + getPaddingTop() + getPaddingBottom() + mTxtImgPadding;
                height = Math.min(tempHeight, heightMeasure);
            } else { //UNSPECIFIED
                int imgHeight = mImg.getHeight();
                int txtHeight = mTxtRect.height();
                int tempHeight = imgHeight + txtHeight + getPaddingTop() + getPaddingBottom() + mTxtImgPadding;
                height = tempHeight;
            }
        }

        // 对 view 的宽高进行赋值 很重要
        setMeasuredDimension(width, height);

    }

    /**
     * 开始绘制
     *
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 边框
        mPaint.setStrokeWidth(4);
        // 描边
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.CYAN);

        // 画一个矩形区域出来
        // 这个view的区域
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

        // 显示内容的区域 view区域 - padding值
        mRect.left = getPaddingLeft();
        mRect.right = width - getPaddingRight();
        mRect.top = getPaddingTop();
        mRect.bottom = height - getPaddingBottom();
        // 绘制内容区域
        canvas.drawRect(getPaddingLeft(), getPaddingTop(), width - getPaddingRight(), height - getPaddingBottom(), mPaint);

        // 为了确定中间点的位置
        //canvas.drawCircle(width / 2, height, 10, mPaint);

        mPaint.setStyle(Paint.Style.FILL);

        // 首先绘制文字
        // 1. 设置文字大小
        if (mTxtSize == 0)
            mTxtSize = DEFAULT_TXT_SIZE;
        mPaint.setTextSize(mTxtSize);
        // 2. 设置文字颜色
        if (mTxtColor == NO_VALUE) // 没有设置该值
            mTxtColor = DEFAULT_TXT_COLOR;
        mPaint.setColor(mTxtColor);
        // 3. 设置文字对齐方式
        // 4. 设置文字 根据不同的对齐方式
        if (mTxtGravity == NO_VALUE) // 没有设置该值
            mTxtGravity = DEFAULT_TXT_GRAVITY;
        fm = mPaint.getFontMetrics();
        float topY = mRect.bottom + fm.top;
        float ascentY = mRect.bottom + fm.ascent;
        float descentY = mRect.bottom + fm.descent;
        float bottomY = mRect.bottom + fm.bottom;
        switch (mTxtGravity) {
            case CENTER: // 居中
                Log.e("tag", "绘制文字开始的位置 [ " + (width / 2 - mTxtRect.width()) + " ]");
                canvas.drawText(mTxt, width / 2 - mPaint.measureText(mTxt, 0, mTxt.length()) / 2, mRect.bottom, mPaint);
                break;
            case LEFT: // 左对齐
                Log.e("tag", width + "-" + mRect.left + "-" + mTxtRect.width());
                canvas.drawText(mTxt, mRect.left, mRect.bottom, mPaint);
                mPaint.setColor(Color.LTGRAY);
                float baseX = mRect.left;
                mPaint.setTextSize(15);
                // TopLine描画
                canvas.drawLine(baseX, topY, baseX + mRect.width() / 2, topY, mPaint);
                canvas.drawText("top", baseX + mRect.width() / 2, topY, mPaint);
// AscentLine描画
                mPaint.setColor(Color.GREEN);
                canvas.drawLine(baseX, ascentY, baseX + mRect.width() / 2, ascentY, mPaint);
                canvas.drawText("ascent", baseX + mRect.width() / 2, ascentY + 10, mPaint);
// DescentLine描画
                mPaint.setColor(Color.YELLOW);
                canvas.drawLine(baseX, descentY, baseX + mRect.width() / 2, descentY, mPaint);
                canvas.drawText("descent", baseX + mRect.width() / 2, descentY, mPaint);
// ButtomLine描画
                mPaint.setColor(Color.MAGENTA);
                canvas.drawLine(baseX, bottomY, baseX + mRect.width() / 2, bottomY, mPaint);
                canvas.drawText("buttom", baseX + mRect.width() / 2, bottomY + 10, mPaint);
                break;
            case RIGHT: // 右对齐
                Log.e("tag", width + "-" + mRect.right + "-" + mTxtRect.width() + "-" + getWidth());
                canvas.drawText(mTxt, mRect.right - mPaint.measureText(mTxt, 0, mTxt.length()), mRect.bottom, mPaint);
                break;
        }

        // 绘制图片
        // 1. 设置图片的对齐方式
        // 2. 设置图片 根据不同的对齐方式
        //canvas.drawBitmap(mImg, 0, 0, mPaint);
        // 通过下面的API可以设置图片缩放类型
//        canvas.drawBitmap(mImg, null, mRect, mPaint);
    }
}
